/*
 *  FXLog.cpp
 *
 *  Copyright 2015 https://github.com/dqjl111 All rights reserved.
 *
 *  This program is use for fuxi project
 *
 *  Created  by: Zhipeng Lin on 2016-01-30
 *  Modified by: Zhipeng Lin on 2016-01-30
 *  ************************************************************************************ */
#include "base/FXLog.h"
/*AVAILABLE LOG COLORS*/
#define RST  "\x1B[0m"

#define KBLK  "\x1B[30m"
#define KRED  "\x1B[31m"
#define KGRN  "\x1B[32m"
#define KYEL  "\x1B[33m"
#define KBLU  "\x1B[34m"
#define KMAG  "\x1B[35m"
#define KCYN  "\x1B[36m"
#define KWHT  "\x1B[37m"

#define FRLK(x) KBLK x RST
#define FRED(x) KRED x RST
#define FGRN(x) KGRN x RST
#define FYEL(x) KYEL x RST
#define FBLU(x) KBLU x RST
#define FMAG(x) KMAG x RST
#define FCYN(x) KCYN x RST
#define FWHT(x) KWHT x RST

#define BOLD(x)	"\x1B[1m" x RST
#define UNDL(x)	"\x1B[4m" x RST


namespace fx{
namespace log{
src::logger lg;
src::severity_logger<SeverityLevel> slg;


const char* const logColor[] ={
    KCYN,
    KGRN,
    KMAG,
    KYEL,
    KRED,
    KRED
};

logging::formatter getFileFormatter(){
    return expr::stream
                <<"["<<expr::format_date_time(log_timestamp,"%H:%M:%S")
                <<"]"<<expr::if_(expr::has_attr(log_uptime))
                    [
                        expr::stream<<"["<<format_date_time(log_uptime,"%O:%M:%S")<<"]"
                    ]
                <<expr::if_(expr::has_attr(log_scope))
                    [
                        expr::stream<<"["<<expr::format_named_scope(log_scope,keywords::format = "%n")<<"]"
                    ]
                <<expr::if_(expr::has_attr(log_severity))
                    [
                        expr::stream<<"<"<<log_severity<<">"
                    ]
                <<expr::message;
}

logging::formatter getControlFormatter(uint level){
    logging::formatter format;
    if(level == Info){
        format = expr::stream<<logColor[level]
                 <<expr::if_(expr::has_attr(log_scope))
                     [
                         expr::stream<<"["<<expr::format_named_scope(log_scope,keywords::format = "%n")<<"]"
                     ]
                 <<expr::message<<RST;
    }else if(level == Notice){
        format = expr::stream<<logColor[level]
                 <<expr::if_(expr::has_attr(log_scope))
                     [
                         expr::stream<<"["<<expr::format_named_scope(log_scope,keywords::format = "%n")<<"]"
                     ]
                 <<"\n"<<expr::message<<RST;
    }else{
        format = expr::stream<<logColor[level]
                <<expr::if_(expr::has_attr(log_scope))
                    [
                        expr::stream<<"["<<expr::format_named_scope(log_scope,keywords::format = "%n")<<"]"
                    ]
                <<expr::if_(expr::has_attr(log_severity))
                    [
                        expr::stream<<"<"<<log_severity<<">"
                    ]
                <<expr::message<<RST;
    }
    return format;
}
void InitLog(std::string logPath){
    logging::add_common_attributes();

    auto collector = sinks::file::make_collector(
                keywords::target=logPath,        //文件夹名
                keywords::max_size=50*1024*1024,    //文件夹所占最大空间
                keywords::min_free_space=100*1024*1024  //磁盘最小预留空间
                );

    auto fileSink=logging::add_file_log
        (
        keywords::file_name=logPath+"/" +"%Y-%m-%d_%N.log",      //文件名
        keywords::rotation_size=10*1024*1024,       //单个文件限制大小
        keywords::time_based_rotation=sinks::file::rotation_at_time_point(0,0,0)    //每天重建
        );

    auto infoSink=logging::add_file_log
        (
        keywords::file_name=logPath+"/" +"Info-%Y-%m-%d_%N.log",      //文件名
        keywords::rotation_size=10*1024*1024,       //单个文件限制大小
        keywords::time_based_rotation=sinks::file::rotation_at_time_point(0,0,0)    //每天重建
        );

    fileSink->locked_backend()->set_file_collector(collector);
    fileSink->set_filter(log_severity>=Warning);   //日志级别过滤
    fileSink->locked_backend()->scan_for_files();

    infoSink->locked_backend()->set_file_collector(collector);
    infoSink->set_filter(log_severity<=Notice);   //日志级别过滤
    infoSink->locked_backend()->scan_for_files();

    logging::formatter formatter= std::move(getFileFormatter());
    fileSink->set_formatter(formatter);
    fileSink->locked_backend()->auto_flush(true);

    infoSink->set_formatter(formatter);
    infoSink->locked_backend()->auto_flush(true);

    //Add log for console
    for(uint level= Info; level <=Fatal; ++level ){
        auto consoleSink=logging::add_console_log();
        consoleSink->set_filter(log_severity == level);
        consoleSink->set_formatter(getControlFormatter(level));
        logging::core::get()->add_sink(consoleSink);
    }

    logging::core::get()->add_sink(fileSink);
    logging::core::get()->add_sink(infoSink);
}
}
}
